home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / tools / ivl / src / ivl_iv.c < prev    next >
Text File  |  2000-06-23  |  22KB  |  762 lines

  1. /*
  2. #define DEBUG
  3. *    ivl
  4. *
  5. *    アイコンビューワ処理根幹部
  6. *
  7. *    from Jun.26,1999    by dummy.x.(with J-SAGA INDUSTRY)
  8. */
  9. #include    <stddef.h>
  10. #include    <jctype.h>
  11. #include    <string.h>
  12. #include    <sys\dos.h>
  13. #include    <sys\iocs.h>
  14. #include    "comtype.h"
  15. #include    "easymac.h"
  16. #include    "sysconst.h"
  17. #define    GRPH_1024
  18. #define    GRPH_COLOR_16
  19. #include    "scrncom.h"
  20. #include    "dummyc.h"
  21. #include    "hufilec.h"
  22. #include    "iocs_add.h"
  23. #include    "libpt4.h"
  24. #include    "ivl.h"
  25. #include    "mkpathfn.c"
  26.  
  27. /* 定数定義 */
  28.     /* read_pt4() 返値の追加 */
  29. enum {
  30.     RDPT4_TOO_LARGE = RDPT4_RESULT_KAZ,    /* 画像サイズが大きすぎる */
  31.     RDPT4_RESULT_KAZ_APPENDED        /* 追加後の返値コード数 */
  32. };
  33.  
  34. /* 大域変数 */
  35. short screen_width, screen_height;    /* 現在の表示画面サイズ */
  36.     /* 表示パターン数 */
  37. short pat_on_line = DEF_PAT_ON_LINE;    /* 1行の表示数 */
  38. short pat_line_kaz = DEF_PAT_LINE_KAZ;    /* 表示行数 */
  39.     /* 1パターン表示範囲 */
  40. short pat_disp_area_w = DEF_PAT_GRPH_W;                /* 横幅 */
  41. short pat_disp_area_h/* = DEF_PAT_GRPH_H + INF_AREA_HEIGHT*/;    /* 縦高 */
  42. short pat_disp_area_gh = DEF_PAT_GRPH_H;            /* 画像縦高 */
  43.  
  44. /* ファイル内変数 */
  45. static char cur_info_type;            /* 現在表示しているアイコン情報データ種(ivl.h/ICONINFO_~) */
  46. static char old_info_type;            /* 前に表示していたアイコン情報データ種(ivl.h/ICONINFO_~) */
  47. static short pat_on_page;            /* 1ページのパターン数 */
  48. static long cur_page_top_no = -1;        /* 現ページの開始番号 */
  49. static long last_page_top_no;            /* 最終ページの開始番号 */
  50. static short disp_start_x, disp_start_y;    /* パターンリスト表示開始座標 */
  51. static short pat_disp_area_len;            /* 1パターンでのアイコン情報表示文字数 */
  52. static char disp_color_mode;    /* 表示色モード(ivl.h/GPPT4_~) */
  53.                 /* ただし、操作処理ではbit単位で設定を行なっている */
  54.  
  55.  
  56. /* テーブルに登録されたアイコンファイル1画面ぶんに対して指定の処理を行なう
  57. *    引数:    topno    - 処理開始するファイルのテーブル番号
  58. *        dofunc    - ファイル処理関数へのポインタ
  59. *    注記    * ここでは topno の値の補正などは一切行なっていない。
  60. *        このため、おかしな値が渡されればそれ相応におかしな
  61. *        ことになるので気をつけるように。
  62. */
  63. static
  64. void do_job_on_page_icon(long topno, void (*dofunc)(filelist_t *, short, short))
  65. {
  66.     ushort x, y;
  67.     filelist_t *ftblp = arg_file_tblp;
  68.     filelist_t *ftblstop;
  69.  
  70.     /* ループ終了位置決定 */
  71.     x = arg_file_kaz - topno;    /* x=残りのアイコン数 */
  72.     if (x > pat_on_page) {
  73.         x = pat_on_page;
  74.     }
  75.     ftblp += topno;
  76.     ftblstop = ftblp + x;
  77.  
  78.     /* 表示ループ */
  79.     x = disp_start_x;
  80.     y = disp_start_y;
  81.     do {
  82.         /* ファイルに対する処理を行なう */
  83.         (*dofunc)(ftblp, x, y);
  84.  
  85.         /* 座標を進める */
  86.         x += pat_disp_area_w;    /* まず横に進めてみる */
  87.         if ((screen_width - x) < pat_disp_area_w) {    /* ここで表示したら画面範囲を超えてしまう */
  88.             /* 次の行に */
  89.             x = disp_start_x;
  90.             y += pat_disp_area_h;
  91.             if ((screen_height - y) < pat_disp_area_h) {    /* ここで表示したら画面範囲を超えてしまう */
  92.                 break;        /* ループ中断 */
  93.             }
  94.         }
  95.  
  96.         /* 次のファイルへ */
  97.         ftblp++;
  98.  
  99.     } while (ftblp < ftblstop);
  100. }
  101.  
  102. /* 画面横幅を取得する
  103. *    返値:    横幅(dot単位)
  104. *    注記    * 現在の画面モードで値が変化する。
  105. */
  106. #define    get_screen_width() ((_iocs_crtmod(CRTMOD_CHECK) == CRTMOD_768_1024_G16_31)? 768: 512)
  107.  
  108. /* 画面縦高を取得する
  109. *    返値:    縦高(dot単位)
  110. */
  111. #define    get_screen_height()    DEF_SCREEN_HEIGHT    /* 最下行の『操作方法』(文字高+余白)ぶんを減算 */
  112.  
  113. /* パターン1つの表示範囲の大きさを算出
  114. *    引数:    aszkpf    - 表示範囲サイズを優先するフラグ(=!0:優先する)
  115. *            {「優先する」場合、縦横の表示数を画面サイズと範囲サイズから算出する
  116. *             「優先しない」場合、縦横表示数と画面サイズから範囲サイズを算出する
  117. *            }
  118. */
  119. static
  120. void calc_pat_disp_info(int aszkpf)
  121. {
  122.     short scrw, scrh;
  123.     long lasttop;
  124.  
  125.     /* 現在の画面モードの表示画面サイズを取得 */
  126.     scrw = get_screen_width();
  127.     scrh = get_screen_height();
  128.  
  129.     /* 表示範囲サイズを優先するかどうかで算出対象を振り分ける */
  130.     if (aszkpf) {    /* 優先する */
  131.         /* 縦横の表示数を画面サイズと範囲サイズから算出する */
  132.             /* 横数 */
  133.         pat_on_line = scrw / pat_disp_area_w;
  134.         if (pat_on_line <= 0) {    /* 768x512 で表示数が 1 の時に 512x512 に移った場合 */
  135.             pat_on_line = 1;    /* とりあえず1個は表示させる */
  136.         }
  137.             /* 縦数 */
  138.         pat_line_kaz = scrh / pat_disp_area_h;
  139.  
  140.     } else {    /* 優先しない */
  141.         /* 縦横表示数と画面サイズから範囲サイズを算出する */
  142.         pat_disp_area_w = scrw / pat_on_line;
  143.         pat_disp_area_len = pat_disp_area_w / INF_MOJI_WIDTH;
  144.         pat_disp_area_h = scrh / pat_line_kaz;
  145.         pat_disp_area_gh = pat_disp_area_h - INF_AREA_HEIGHT;
  146.     }
  147.  
  148.     /* 表示画面サイズを設定 */
  149.     screen_width = scrw;
  150.     screen_height = scrh;
  151.  
  152.     /* 1ページの表示個数を求めておく */
  153.     pat_on_page = pat_on_line * pat_line_kaz;
  154.  
  155.     /* 最終ページの表示開始番号を求めておく */
  156.     lasttop = (arg_file_kaz + (pat_on_line - 1)) - pat_on_page;
  157.     lasttop = lasttop - (lasttop % pat_on_line);    /* lasttop / pat_on_line * pat_on_line) */
  158.     if (lasttop < 0) {
  159.         lasttop = 0;
  160.     }
  161.     last_page_top_no = lasttop;
  162.  
  163.     /* 表示範囲と表示個数と画面サイズから表示開始座標を算出する */
  164.     disp_start_x = (screen_width - (pat_disp_area_w * pat_on_line)) / 2;
  165.     disp_start_y = (screen_height - (pat_disp_area_h * pat_line_kaz)) / 2;
  166. }
  167.  
  168. /* .PT4 ファイル読み込みでのエラーメッセージ表示
  169. *    引数:    ercode    - read_pt4() エラーコード(RDPT4_~)
  170. *        fnamp    - エラーを起こしたファイル名へのポインタ
  171. *        tx,ty    - アイコン表示範囲開始座標
  172. *    注記    * 「正常終了」(RDPT4_SUCCESS)の場合、ここでは何もしない。
  173. */
  174. static
  175. void draw_pt4_err_msg(int ercode, const char *fnamp, ushort tx, ushort ty)
  176. {
  177.     static const char *msgtbl[][2] = {
  178.         {"ファイル", "読込失敗"},
  179.         {" メモリ", "確保失敗"},
  180.         {"アイコン", "ではない"},
  181.         {" サイズ", "オーバー"},
  182.     };
  183.  
  184.     if ((ercode > RDPT4_SUCCESS) && (ercode < RDPT4_RESULT_KAZ_APPENDED)) {
  185.         --ercode;
  186.         /* 座標算出 */
  187.         tx += (pat_disp_area_w - (4 * 24)) / 2;    /*横方向センタリング */
  188. #if    defined(LIKE_SX_WINDOW)
  189.         ty += ((pat_disp_area_gh) - (2 * 24));
  190. #else
  191.         ty += INF_AREA_HEIGHT;
  192. #endif
  193.         /* 1行目表示 */
  194.         symbol_pt4_error(msgtbl[ercode][0], tx, ty);
  195.         /* 2行目表示 */
  196.         ty += 24;
  197.         symbol_pt4_error(msgtbl[ercode][1], tx, ty);
  198.     }
  199. }
  200.  
  201. /* .PT4 データをグラフィック表示する
  202. *    引数:    pt4datp    - 表示データへのポインタ
  203. *        tx,ty    - アイコン表示範囲開始座標
  204. *    注記    * 「正常終了」(RDPT4_SUCCESS)の場合、ここでは何もしない。
  205. */
  206. static
  207. void draw_pt4_data(const pt4_struct_t *pt4datp, ushort tx, ushort ty)
  208. {
  209.     ushort x, y;
  210.  
  211.     /* 表示座標算出 */
  212. #if    defined(LIKE_SX_WINDOW)
  213.     x = tx + ((pat_disp_area_w - pt4datp->width) / 2);
  214.     y = ty + ((pat_disp_area_gh) - pt4datp->height);
  215. #else    /* defined(LIKE_SX_WINDOW) */
  216.     x = tx + ((pat_disp_area_w - pt4datp->width) / 2);
  217.     y = ty + INF_AREA_HEIGHT;
  218. #endif    /* defined(LIKE_SX_WINDOW) */
  219.  
  220.     /* 描画 */
  221.     gput_pt4(pt4datp, x, y);
  222. }
  223.  
  224. /* 文字列を規定字数に切り詰める
  225. *    引数:    bufp    - 切り詰める文字列バッファアドレス
  226. *        len    - 切り詰める字数
  227. *    返値:    bufp の値
  228. *    注記    * bufp の len-1 文字を残し、len 文字目には '>' を書き込む。
  229. *        * 切り詰めた後の最後の1文字が SJIS 漢字1バイト目だったら、
  230. *        '・' で踏み潰す。
  231. *        * bufp が len 文字以上あるかどうかは、ここでは判定しない。
  232. *        その必要があれば、呼び出し側が行なうこと。
  233. */
  234. static
  235. char *cut_str_in_length(char *bufp, short len)
  236. {
  237.     char *cp = bufp + len;
  238.  
  239.     *cp = '\0';    /* 文字列を完結させる */
  240.     *--cp = '>';    /* 「続く」文字を付加 */
  241.  
  242.     --cp;            /* 切り詰め最後の1文字 */
  243.     if (iskanji(*cp)) {    /* が漢字1バイト目なら */
  244.         *cp = '・';    /* 「潰した」文字を付加 */
  245.     }
  246.  
  247.     return bufp;
  248. }
  249.  
  250. /* アイコン情報を表示/消去する
  251. *    引数:    flistp    - 表示アイコンファイルのリストへのポインタ
  252. *        tx,ty    - アイコン表示範囲開始座標
  253. *        dtype    - 表示アイコン情報
  254. *        dispf    - 消去/表示フラグ(=0:消去/=!0:表示)
  255. */
  256. static
  257. void symbol_nameinfo_line    \
  258. (const filelist_t *flistp, ushort tx, ushort ty, char dtype, char dispf)
  259. {
  260.     short x, y;
  261.     long msgw;
  262.     const char *msgp;
  263.     char buf[768 / INF_MOJI_WIDTH + 1];
  264.  
  265.     /* 表示/消去情報に応じた設定 */
  266.     switch (dtype) {
  267.     default:        /* ワケわかんない値...とりあえずファイル名を表示 */
  268.     case ICONINFO_NAME:    /* ファイル名 */
  269.         msgp = flistp->fbuf.name;
  270.         break;
  271.     case ICONINFO_PATH:    /* パス名 */
  272.         msgp = flistp->pathp;
  273.         if (is_null_str(msgp)) {    /* 空文字ならカレントパス */
  274.             msgp = "<current>";    /* 無表示だとアレなので何か表示する */
  275.         }
  276.         break;
  277.     case ICONINFO_INFO:    /* 画像情報 */
  278.         msgp = "W:xxx/H:xxx";
  279.         if ((dispf)            /* 表示する */
  280.          && (flistp->wdots >= 0)    /* ちゃんとアイコンファイルだった */
  281.         ) {                /* ↑の全てを満たしていれば */
  282.             /* 表示文字列を作成する */
  283.             strcpy(buf, msgp);    /* ベース文字列を複写 */
  284.                 /* "xxx" を置き換える */
  285.             ltodecstr(buf + 2, flistp->wdots, 3, ' ');
  286.             buf[5] = '/';    /* ↑で書かれた '\0' を上書き */
  287.             ltodecstr(buf + 8, flistp->hdots, 3, ' ');
  288.             msgp = buf;
  289.         }
  290.         break;
  291.     }
  292.     msgw = strlen(msgp);    /* 表示文字数 */
  293.     /* 表示範囲を超えていたら切り詰める */
  294.     if (!chkbit(state_flag_bits, FBIT_NOCUTINF)) {    /* 切り詰めなくてよければ切り詰めない */
  295.         if (msgw > pat_disp_area_len) {
  296.             msgw = pat_disp_area_len;
  297.             if (msgp != buf) {
  298.                 memcpy(buf, msgp, msgw);
  299.                 msgp = buf;
  300.             }
  301.             cut_str_in_length(buf, msgw);
  302.         }
  303.     }
  304.     msgw *= INF_MOJI_WIDTH;    /* 表示文字列幅(dot単位)を算出 */
  305.  
  306.     /* 表示座標算出 */
  307.     x = tx + ((pat_disp_area_w - msgw) / 2);
  308. #if    defined(LIKE_SX_WINDOW)
  309.     y = ty + pat_disp_area_gh;
  310. #else    /* defined(LIKE_SX_WINDOW) */
  311.     y = ty;
  312. #endif    /* defined(LIKE_SX_WINDOW) */
  313.  
  314.     /* 表示/消去 */
  315.     if (dispf) {    /* 表示 */
  316.         y += INF_AREA_DIF;    /* 上との余白ぶんを加算 */
  317.         symbol_6x12(msgp, x, y);
  318.     } else {    /* 消去 */
  319.         boxfill_in_area(x, y, msgw, INF_AREA_HEIGHT);
  320.     }
  321. }
  322.  
  323. /* アイコンファイルデータを指定座標に表示する
  324. *    引数:    flistp    - 表示アイコンファイルのリストへのポインタ
  325. *        tx,ty    - 表示座標
  326. *    返値:    read_pt4() エラーコード(RDPT4_~)
  327. */
  328. static
  329. void disp_icon_one_pat(filelist_t *flistp, short tx, short ty)
  330. {
  331.     int uke;
  332.     const char *const fnamp = flistp->fbuf.name;
  333.     pt4_struct_t *rbufp = NULL;
  334.  
  335.     /* ファイルを読み込み/確認する */
  336.     uke = flistp->rdresult;    /* 先行読み込みの返値 */
  337.     if (uke != RDPT4_SUCCESS) {    /* 先行読み込み失敗 */
  338.  
  339.         /* 読み込みに再挑戦してみる */
  340.         if (uke != RDPT4_ILL_FORMAT) {    /* 不正ファイルでなければ */
  341.             uke = read_pt4(&rbufp
  342.                 , make_path_filename(flistp->pathp, &flistp->fbuf));
  343.         }
  344.  
  345.     } else {            /* 先行読み込み済 */
  346.         rbufp = flistp->rdbufp;    /* 読み込みデータアドレスを設定 */
  347.     }
  348.  
  349.     if (uke == RDPT4_SUCCESS) {    /* 読み込みは成功した */
  350.         short w = rbufp->width, h = rbufp->height;
  351.  
  352.         /* 画像サイズをファイルリストの方にも保持 */
  353.         flistp->wdots = w;
  354.         flistp->hdots = h;
  355.  
  356.         /* 画像サイズが表示範囲に収まるか確認 */
  357.         if ((w > pat_disp_area_w)
  358.          || (h > (pat_disp_area_gh))
  359.         ) {        /* 横/縦どっちかがデカすぎたら */
  360.             uke = RDPT4_TOO_LARGE;    /* エラー扱い */
  361.         }
  362.     }
  363.  
  364.     /* 画像描画 */
  365.     if (uke == RDPT4_SUCCESS) {    /* 正常終了 */
  366.         /* 読み込んだ画像を描画 */
  367.         draw_pt4_data(rbufp, tx, ty);
  368.     } else {            /* エラーあり */
  369.         /* エラーメッセージ描画 */
  370.         draw_pt4_err_msg(uke, fnamp, tx, ty);
  371.     }
  372.  
  373.     /* アイコン情報描画 */
  374.     symbol_nameinfo_line(flistp, tx, ty, cur_info_type, !0);
  375.  
  376.     /* 後始末 */
  377.     if (flistp->rdresult != RDPT4_SUCCESS) {    /* 先行読み込みに失敗していた */
  378.         /* 読み込みメモリはここで確保したものなので解放しておく */
  379.         free_mem(rbufp);
  380.     }
  381. }
  382.  
  383. /* テーブルに登録されたアイコンファイルを指定番目からつらつらと表示する
  384. *    引数:    topno    - 表示開始するファイルのテーブル番号
  385. *    注記    * ここでは topno の値の補正などは一切行なっていない。
  386. *        このため、おかしな値が渡されればそれ相応におかしな
  387. *        ことになるので気をつけるように。
  388. */
  389. static
  390. void disp_icon_one_page(long topno)
  391. {
  392.     /* 一斉消去 */
  393.     _iocs_wipe();
  394.  
  395.     /* アイコン表示 */
  396.     do_job_on_page_icon(topno, disp_icon_one_pat);
  397. }
  398.  
  399. /* 状況に応じて適切なガイドメッセージを表示する
  400. *    引数:    topno    - 表示開始するアイコンファイルのテーブル番号
  401. */
  402. static
  403. void print_guide_msg(long topno)
  404. {
  405.     int col = 8 + 4;    /* 8+4 で反転+強調表示の意 */
  406.     int ch;
  407.     int endno;
  408.     const char *gmsgp;
  409.  
  410.     /* 表示メッセージ/色の決定 */
  411.     if (arg_file_kaz <= pat_on_page) {    /* アイコン数が1ページに収まる */
  412.         gmsgp = "終:[ESC], MOUSE L+R  画面:[←][→]";
  413.         col += 2;
  414.  
  415.     } else if (topno <= 0) {        /* 2ページ以上:最初のページ */
  416.         gmsgp = "終:[ESC], MOUSE L+R  次頁:[ROLL UP], MOUSE-L";
  417.         col += 2;
  418.  
  419.     } else if (topno >= last_page_top_no) {    /* 2ページ以上:最後のページ */
  420.         gmsgp = "終:[ESC], MOUSE L+R  前頁:[ROLL DOWN], MOUSE-R";
  421.         col += 2;
  422.  
  423.     } else {                /* 3ページ以上:途中のページ */
  424.         gmsgp = "終:[ESC], MOUSE L+R  次/前頁:[ROLL UP/DOWN], MOUSE-L/R";
  425.         col += 1;
  426.     }
  427.     /* メッセージ表示 */
  428.     if (cur_info_type == ICONINFO_INFO) {    /* アイコン情報表示時 */
  429.         /* 表示可能画像サイズを "<横幅>x<縦高>" で表示 */
  430.         ch = 'x';
  431.         topno = pat_disp_area_w;
  432.         endno = pat_disp_area_gh;
  433.     } else {                /* それ以外 */
  434.         /* 表示開始番号と登録アイコン数を "<開始>/<登録数>" で表示 */
  435.         ch = '/';
  436.         endno = arg_file_kaz;
  437.     }
  438.     print_message_on_guideline(gmsgp, col, topno, endno, ch);
  439. }
  440.  
  441. /* 1画面表示する
  442. *    引数:    topno    - 表示開始するアイコンファイルのテーブル番号
  443. *    注記    * この関数が表示するのは次のものである。:
  444. *            ・1画面分のアイコン画像
  445. *            ・テキスト最下行のガイドメッセージ
  446. */
  447. static
  448. void disp_one_page(long topno)
  449. {
  450.     disp_icon_one_page(topno);    /* アイコン表示 */
  451.     print_guide_msg(topno);        /* ガイドメッセージ表示 */
  452. }
  453.  
  454. /* ページ表示開始番号を有効範囲内に補正する
  455. *    引数:    topno    - 表示開始番号
  456. *    返値:    補正後の番号
  457. */
  458. static
  459. long adjust_in_page_top_area(long topno)
  460. {
  461.     /* 最大番号を上回ってる */
  462.     if (topno > last_page_top_no) {
  463.         topno = last_page_top_no;
  464.     }
  465.     /* 最小番号を下回ってる
  466.     *    上と else if ~ で繋げないのは
  467.     *    last_page_top_no < 0 だった場合の処置
  468.     */
  469.     if (topno < 0) {
  470.         topno = 0;
  471.     }
  472.     return topno;
  473. }
  474.  
  475. /* ページ表示開始番号を適切に移動する
  476. *    引数:    code    - 移動量指示操作コード(CTRL_~PAGE,CTRL_~LINE)
  477. *    注記    *c ファイル内変数 cur_page_top_no を直接参照し、
  478. *        その値を直接書き替える。
  479. */
  480. static
  481. void move_page_top(int ccode)
  482. {
  483.     long topno = cur_page_top_no;
  484.  
  485.     /* 仮に番号を指示通りに移動させる */
  486.     switch (ccode) {
  487.     default:    /* その他 */
  488.     case CTRL_NEXTPAGE:    /* 次ページに移動 */
  489.         topno += pat_on_page;
  490.         break;
  491.     case CTRL_NEXTLINE:    /* 次行に移動 */
  492.         topno += pat_on_line;
  493.         break;
  494.     case CTRL_BACKLINE:    /* 前行に移動 */
  495.         topno -= pat_on_line;
  496.         break;
  497.     case CTRL_BACKPAGE:    /* 前ページに移動 */
  498.         topno -= pat_on_page;
  499.         break;
  500.     case CTRL_FIRSTPAGE:    /* 最初ページ/最終ページに移動 */
  501.         if (cur_page_top_no == 0) {    /* 今最初ページにいたら */
  502.             topno = last_page_top_no;    /* 最終ページへ */
  503.         } else {            /* 最初以外のページにいたら */
  504.             topno = 0;            /* 最初のページへ */
  505.         }
  506.         break;
  507.     }
  508.  
  509.     /* 移動後の番号が範囲外になってたら補正する */
  510.     topno = adjust_in_page_top_area(topno);
  511.  
  512.     /* 移動の結果が現在値と異なってたら表示する */
  513.     if (topno != cur_page_top_no) {
  514.         cur_page_top_no = topno;
  515.         disp_one_page(topno);
  516.     }
  517. }
  518.  
  519. /* 画面モードの変更
  520. *    引数:    code    - 画面モード変更指示操作コード(CTRL_WIDTH_~)
  521. *    注記    * 画面モード値取得の際、
  522. *            CTRL_WIDTH_512,CTRL_WIDTH_768 がこの順序で
  523. *            定義値が 1 違いで定義されている
  524. *        ことを前提にした処理をしている。
  525. */
  526. static
  527. void change_screen_mode(int ccode)
  528. {
  529.     long topno;
  530.     char crtmodetbl[2] = {CRTMOD_512_1024_G16_31, CRTMOD_768_1024_G16_31};
  531.  
  532.     /* 画面モード変更 */
  533.     topno = crtmodetbl[ccode - CTRL_WIDTH_512];    /* とりあえず topno を流用 */
  534.     if (topno == _iocs_crtmod(CRTMOD_CHECK)) {    /* 現モードと変更後が同じなら */
  535.         return;                    /* 即座に返ってしまう */
  536.     }
  537.     (void)_iocs_crtmod(topno);
  538.     _iocs_g_clr_on();    /* グラフィッククリア&表示 */
  539.  
  540.     /* 表示に必要な情報を再設定 */
  541.         /* リスト表示情報 */
  542.     calc_pat_disp_info(!0);    /* 表示範囲サイズを優先する */
  543.         /* グラフィックパレット */
  544.     set_gpalet_pt4(disp_color_mode);
  545.  
  546.     /* 表示開始番号を適切?に補正 */
  547.     topno = cur_page_top_no;        /* 現在の表示番号に */
  548.     topno = topno - (topno % pat_on_line);    /* 一番近い行開始番号を求める */
  549.     topno = adjust_in_page_top_area(topno);    /* その値をきっちり範囲内に補正して */
  550.     cur_page_top_no = topno;        /* 設定しておく */
  551.     disp_one_page(topno);            /* その番号で画面表示 */
  552. }
  553.  
  554. /* アイコン情報の表示を変更する
  555. *    引数:    flistp    - 表示アイコンファイルの登録リストへのポインタ
  556. *        tx,ty    - 表示座標
  557. */
  558. static
  559. void change_one_icon_info(filelist_t *flistp, short tx, short ty)
  560. {
  561.     symbol_nameinfo_line(flistp, tx, ty, old_info_type, 0);        /* 消してから */
  562.     symbol_nameinfo_line(flistp, tx, ty, cur_info_type, !0);    /* 改めて書く */
  563. }
  564.  
  565. /* アイコン情報表示の切替
  566. *    引数:    ntype    - 新規表示情報データ種(ICONINFO_~)
  567. *    注記    * 現在表示しているデータ種と ntype が同じでも表示を行なう。
  568. *        * ntype には、必ず規定の値を渡すように。
  569. */
  570. static
  571. void change_icon_info_one_page(char ntype)
  572. {
  573.     old_info_type = cur_info_type;
  574.     cur_info_type = ntype;
  575.  
  576.     /* アイコン表示 */
  577.     do_job_on_page_icon(cur_page_top_no, change_one_icon_info);
  578.  
  579.     /* ガイドライン表示 */
  580.     print_guide_msg(cur_page_top_no);
  581. }
  582.  
  583. /* ユーザ操作に応じた処理を行なう
  584. *    引数:    ccode    - 操作コード(CTRL_~)
  585. *    返値:    終了指示が出てたら !0、でなければ 0
  586. */
  587. static
  588. int accept_user_ctrl(int ccode)
  589. {
  590.     int result = 0;
  591.  
  592.     switch (ccode) {
  593.     case CTRL_QUIT:        /* 終了 */
  594.     case CTRL_QUIT_KPSCR:    /* 終了:画面状態維持 */
  595.         result = !0;
  596.         break;
  597.     case CTRL_NEXTPAGE:    /* 次ページに移動 */
  598.     case CTRL_NEXTLINE:    /* 次行に移動 */
  599.     case CTRL_BACKLINE:    /* 前行に移動 */
  600.     case CTRL_BACKPAGE:    /* 前ページに移動 */
  601.     case CTRL_FIRSTPAGE:    /* 1ページ目に戻る */
  602.         move_page_top(ccode);
  603.         break;
  604.     case CTRL_WIDTH_512:    /* 表示画面 512×512 モードに */
  605.     case CTRL_WIDTH_768:    /* 表示画面 768×512 モードに */
  606.         change_screen_mode(ccode);
  607.         break;
  608. #if    0
  609.     case CTRL_INFO_CHG:    /* アイコン情報表示切替 */
  610.         change_icon_info_one_page(((uchar)cur_info_type + 1) % ICONINFO_KAZ);
  611.         break;
  612. #endif
  613.     case CTRL_INFO_NAME:    /* アイコンファイル名表示 */
  614.         change_icon_info_one_page(ICONINFO_NAME);
  615.         break;
  616.     case CTRL_INFO_PATH:    /* アイコンパス名表示 */
  617.         change_icon_info_one_page(ICONINFO_PATH);
  618.         break;
  619.     case CTRL_INFO_INFO:    /* アイコン画像情報表示 */
  620.         change_icon_info_one_page(ICONINFO_INFO);
  621.         break;
  622.      case CTRL_DISP_NORM:        /* 画像通常表示 */
  623.         disp_color_mode = 0;
  624.         set_gpalet_pt4(disp_color_mode);
  625.         break;
  626.     case CTRL_DISP_NGTV:        /* 画像色反転表示 */
  627.     case CTRL_DISP_MONO:        /* 画像白黒表示 */
  628.         /* グラフィックパレットを変更 */
  629.         ccode -= CTRL_DISP_NORM;    /* NGTV,MONO → (1<<0),(1<<1) */
  630.         disp_color_mode ^= ccode;    /* bit0,1 をトグル */
  631.         set_gpalet_pt4(disp_color_mode);
  632.         break;
  633.     case CTRL_NONE:        /* 操作なし(現状維持) */
  634.         /* 操作がないんだから何もしない */
  635.         /* fall through */
  636.     default:        /* その他 */
  637.         /* 何すりゃいいのかわからないから何もしない */
  638.         break;
  639.     }
  640.     return result;
  641. }
  642.  
  643. /* アイコン画像サイズから1ページの表示数を算出/設定する
  644. *    注記    * 算出するように指定されていなければ何もしない。
  645. */
  646. static
  647. void calc_patkaz_by_grphsize(void)
  648. {
  649.     short grpw = pat_disp_area_w;
  650.     short grph = pat_disp_area_gh;
  651.     ushort unlimf = chkbit(state_flag_bits, FBIT_BYSZ_UNLIM);
  652.  
  653.     /* 「最大画像サイズで算出」指示があれば */
  654.     if (chkbit(state_flag_bits, FBIT_BYSZ_FINDMX)) {
  655.         /* 登録アイコンの最大サイズを取得する */
  656.         filelist_t *ftblp = arg_file_tblp + arg_file_kaz;
  657.  
  658.         grpw = grph = -1;
  659.         while (ftblp > arg_file_tblp) {
  660.             --ftblp;
  661.             if (grpw < ftblp->wdots) {    /* ファイルの方が大きければ */
  662.                 grpw = ftblp->wdots;    /* そっちを入れる */
  663.             }
  664.             if (grph < ftblp->hdots) {    /* ファイルの方が大きければ */
  665.                 grph = ftblp->hdots;    /* そっちを入れる */
  666.             }
  667.         }
  668.  
  669.         if (grpw <= 0) {    /* 一つもアイコンファイルがなかった */
  670.             /* 表示数を標準にする */
  671.             pat_on_line = DEF_PAT_ON_LINE;        /* 1行の表示数 */
  672.             pat_line_kaz = DEF_PAT_LINE_KAZ;    /* 表示行数 */
  673.             return;    /* ここで返ってしまう */
  674.  
  675.         } else {        /* 一つでもアイコンファイルがあった */
  676.             pat_disp_area_w = grpw;
  677.             pat_disp_area_gh = grph;
  678.         }
  679.     }
  680.  
  681.     /* 表示範囲全体の縦高を設定しておく */
  682.     grph += INF_AREA_HEIGHT;
  683.     pat_disp_area_h = grph;
  684.  
  685.     /* 表示数を設定 */
  686.         /* 縦 */
  687.     grph = get_screen_height() / grph;
  688.     if (grph < PAT_LINE_KAZ_MIN) {
  689.         grph = PAT_LINE_KAZ_MIN;
  690.     } else if (!unlimf && (grph > PAT_LINE_KAZ_MAX)) {
  691.         grph = PAT_LINE_KAZ_MAX;
  692.     }
  693.         /* 横 */
  694.     grpw = get_screen_width() / grpw;
  695.     if (grpw < PAT_ON_LINE_MIN) {
  696.         grpw = PAT_ON_LINE_MIN;
  697.     } else if (!unlimf && (grpw > PAT_ON_LINE_MAX)) {
  698.         grpw = PAT_ON_LINE_MAX;
  699.     }
  700.     pat_on_line = grpw;    /* 1行の表示数 */
  701.     pat_line_kaz = grph;    /* 表示行数 */
  702. }
  703.  
  704. /* 表示情報の初期設定
  705. */
  706. void init_view_info(void)
  707. {
  708.     if (chkbit(state_flag_bits, FBIT_PAGE_BY_SIZE)) {
  709.         calc_patkaz_by_grphsize();
  710.     }
  711.     calc_pat_disp_info(0);
  712. }
  713.  
  714. /* アイコンビューワ処理
  715. *    返値:    無事に終了すれば 0、何か問題があったら !0
  716. */
  717. int view_icons(void)
  718. {
  719.     int result = 0;
  720.     int ccode;
  721.     short crtmode_keep, fnkmode_keep;
  722.  
  723.     /* 下準備 */
  724.     crtmode_keep = _dos_c_width(C_WIDTH_CHECK);    /* 画面モード保持 */
  725.     (void)_iocs_crtmod(CRTMOD_768_1024_G16_31);    /* 画面モード変更 */
  726.     fnkmode_keep = _dos_c_fnkmod(C_FNKMOD_LINE);    /* ファンクションキー通常行化 */
  727.     _iocs_g_clr_on();    /* グラフィッククリア&表示 */
  728.     _iocs_b_curoff();    /* 取敢えずカーソルを消しとく */
  729.     _iocs_ms_init();    /* マウス初期化 */
  730.     _iocs_skey_off();    /* ソフトキーボード表示禁止 */
  731.     set_gpalet_pt4(disp_color_mode);    /* グラフィックパレットの準備 */
  732.     init_view_info();    /* 表示情報の設定 */
  733.  
  734.     /* ユーザ操作に応じて表示変更・・・を延々と繰り返す */
  735.     ccode = CTRL_FIRSTPAGE;    /* まずは「最初から表示」を指示 */
  736.     do {
  737.         /* ユーザ操作に反応する */
  738.         accept_user_ctrl(ccode);
  739.  
  740.         /* ユーザ操作を受け付ける */
  741.         ccode = get_user_ctrl();
  742.  
  743.     } while ((ccode != CTRL_QUIT) && (ccode != CTRL_QUIT_KPSCR));
  744.                     /* 終了指示されたらループ終了 */
  745.  
  746.     /* 後始末 */
  747.     _iocs_b_color(3);    /* テキスト表示色を「白」に戻す */
  748.     _iocs_skey_reset();    /* ソフトキーボードをユーザ制御に戻す */
  749.     _iocs_b_curon();    /* 取敢えずカーソルを表示しとく */
  750.     kflush_inline();    /* キーバッファクリア */
  751.     (void)_dos_c_fnkmod(fnkmode_keep);    /* ファンクションキー状態を元に戻す */
  752.         /* 画面モードを元に戻す */
  753.     if ((ccode == CTRL_QUIT)        /* 通常終了指示されてても */
  754.      && (_iocs_bitsns(0x0e) != 0x01)    /* [SHIFT]が押されてたら戻さない */
  755.     ) {
  756.         (void)_dos_c_width(crtmode_keep);
  757.     }
  758.  
  759.     return result;
  760. }
  761.  
  762.